﻿using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace UpdateApp
{
    public class FileHelper
    {
        /// <summary>
        /// 获取上传目录
        /// </summary>
        /// <returns></returns>
        public static string GetUploadPath()
        {
            string path = System.AppDomain.CurrentDomain.BaseDirectory;
            string dirname = GetDirName();
            string uploadDir = path + dirname;

            CreateDir(uploadDir);

            return uploadDir;
        }

        /// <summary>
        /// 获取临时目录
        /// </summary>
        /// <returns></returns>
        public static string GetTempPath()
        {

            string path = System.AppDomain.CurrentDomain.BaseDirectory;
            string dirname = GetTempDirName();
            string uploadDir = path + dirname;

            CreateDir(uploadDir);

            return uploadDir;
        }

        public static string GetDirName()
        {
            return System.Configuration.ConfigurationManager.AppSettings["uploaddir"];

        }

        public static string GetTempDirName()
        {
            return System.Configuration.ConfigurationManager.AppSettings["tempdir"];
        }

        public static void CreateDir(string path)
        {
            if (!System.IO.Directory.Exists(path))
                System.IO.Directory.CreateDirectory(path);
        }

        public static void DelDirectories()
        {
            string[] paths = Directory.GetDirectories(GetUploadPath());

            List<DirectoryInfo> list = new List<DirectoryInfo>();

            int day = int.Parse(System.Configuration.ConfigurationManager.AppSettings["backup"]);

            string temp = FileHelper.GetTempDirName().Replace(FileHelper.GetDirName() + "/", "");

            if (paths != null && paths.Length > 0)
            {
                foreach (string item in paths)
                {
                    if (!item.EndsWith(temp))
                        list.Add(new DirectoryInfo(item));
                }
            }

            foreach (DirectoryInfo item in list)
            {
                TimeSpan ts = DateTime.Now - item.LastWriteTime;

                if (ts.Days >= day)
                    item.Delete(true);
            }
        }

        protected static string GetMD5HashFromFile(string fileName)
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            MD5 md5 = new MD5CryptoServiceProvider();

            byte[] retVal = md5.ComputeHash(file);
            file.Close();

            ASCIIEncoding enc = new ASCIIEncoding();

            return enc.GetString(retVal);
        }

        public static Dictionary<string, string> GetFiles(string date)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();

            string path = GetUploadPath();

            if (!string.IsNullOrEmpty(date))
                path = Path.Combine(path, date);

            if (Directory.Exists(path))
            {
                DirectoryInfo dirinfo = new DirectoryInfo(path);

                FileInfo[] Files = dirinfo.GetFiles();

                Array.Sort<FileInfo>(Files, new FileComparer());

                foreach (var item in Files)
                    //if (item.Attributes != FileAttributes.Hidden)
                    if (item.Name != "Log.txt")
                        dic.Add(item.Name, GetString(item.Length) + "|" + item.LastWriteTime.ToShortTimeString());
            }

            return dic;
        }


        public static List<string> ReadFileList(string filePath)
        {
            List<string> list = new List<string>();

            try
            {
                FileStream file = null;
                StreamReader read = null;

                if (File.Exists(filePath))
                {
                    file = new FileStream(filePath, FileMode.Open);

                    read = new StreamReader(file, Encoding.UTF8);

                    string str = read.ReadLine();

                    while (str != null)
                    {
                        if (!string.IsNullOrEmpty(str))
                            list.Add(str);

                        str = read.ReadLine();
                    }

                    file.Dispose();
                    read.Dispose();
                }
            }
            catch (Exception)
            {
            }

            return list;
        }

        public static void WriteListToTextFile(List<string> list, string txtFile)
        {
            FileStream fs = new FileStream(txtFile, FileMode.Create, FileAccess.Write);

            StreamWriter sw = new StreamWriter(fs);

            sw.Flush();

            // 使用StreamWriter来往文件中写入内容 
            sw.BaseStream.Seek(0, SeekOrigin.Begin);

            for (int i = 0; i < list.Count; i++) sw.WriteLine(list[i]);

            //关闭此文件 
            sw.Flush();
            sw.Close();
            fs.Close();
        }

        private string GetNetworkFile(string strURL)
        {
            HttpWebRequest request;

            try
            {
                // 创建一个HTTP请求
                request = (HttpWebRequest)WebRequest.Create(strURL);

                HttpWebResponse response;
                response = (HttpWebResponse)request.GetResponse();

                StreamReader myreader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                string responseText = myreader.ReadToEnd();
                myreader.Close();

                return responseText;
            }
            catch (Exception)
            {
                return "";
            }
        }

        public static string GetString(long b)
        {
            const int GB = 1024 * 1024 * 1024;
            const int MB = 1024 * 1024;
            const int KB = 1024;

            if (b / GB >= 1)
                return Math.Round(b / (float)GB, 2) + "GB";

            if (b / MB >= 1)
                return Math.Round(b / (float)MB, 2) + "MB";

            if (b / KB >= 1)
                return Math.Round(b / (float)KB, 2) + "KB";

            return b + "B";
        }

        /// <summary>
        /// 压缩文件成zip
        /// </summary>
        /// <returns></returns>
        public static bool CreateZipFile(List<string> fileList, string password = "")
        {
            bool isZip = false;

            try
            {
                //一个文件时按此文件名命名，多个文件时随机命名
                string fileZip = fileList.Count == 1 ? Path.Combine(Path.GetDirectoryName(fileList[0]), Path.GetFileNameWithoutExtension(fileList[0]) + ".zip") : Path.Combine(Path.GetDirectoryName(fileList[0]), Path.GetRandomFileName() + ".zip");

                using (ZipOutputStream s = new ZipOutputStream(File.Create(fileZip)))
                {
                    s.SetLevel(9); // 压缩级别 0-9

                    if (!string.IsNullOrEmpty(password))
                        s.Password = password;

                    byte[] buffer = new byte[4096]; //缓冲区大小
                    foreach (string file in fileList)
                    {
                        ZipEntry entry = new ZipEntry(Path.GetFileName(file));
                        entry.DateTime = DateTime.Now;
                        s.PutNextEntry(entry);

                        using (FileStream fs = File.OpenRead(file))
                        {
                            int sourceBytes;

                            do
                            {
                                sourceBytes = fs.Read(buffer, 0, buffer.Length);
                                s.Write(buffer, 0, sourceBytes);
                            } while (sourceBytes > 0);

                            fs.Close();
                            fs.Dispose();
                        }

                        File.Delete(file);
                    }

                    s.Finish();
                    s.Close();

                    isZip = true;
                }
            }
            catch (Exception ex)
            {

            }

            return isZip;
        }

        /// <summary>
        /// 压缩文件成zip
        /// </summary>
        /// <param name="fileZip">压缩成zip文件的绝对路径</param>
        /// <param name="fileName">被压缩指定文件的名字</param>
        /// <param name="zipFilePath"></param>
        /// <returns></returns>
        public bool CreateZipFile(string fileZip, string fileName, string zipFilePath, string password)
        {

            bool isZip = false;
            if (!Directory.Exists(zipFilePath))
            {
                return isZip;
            }
            try
            {
                string[] filenames = Directory.GetFiles(zipFilePath);
                using (ZipOutputStream s = new ZipOutputStream(File.Create(fileZip)))
                {
                    s.SetLevel(9); // 压缩级别 0-9
                    if (!string.IsNullOrEmpty(password))
                        s.Password = password;

                    byte[] buffer = new byte[4096]; //缓冲区大小
                    foreach (string file in filenames.ToList())
                    {
                        if (file == zipFilePath + fileName)//指定被压缩文件的绝对路径
                        {
                            ZipEntry entry = new ZipEntry(Path.GetFileName(file));
                            entry.DateTime = DateTime.Now;
                            s.PutNextEntry(entry);

                            using (FileStream fs = File.OpenRead(file))
                            {
                                int sourceBytes;
                                do
                                {
                                    sourceBytes = fs.Read(buffer, 0, buffer.Length);
                                    s.Write(buffer, 0, sourceBytes);
                                } while (sourceBytes > 0);

                                fs.Close();
                                fs.Dispose();
                            }

                            break;
                        }
                    }

                    s.Finish();
                    s.Close();

                    isZip = true;
                }
            }
            catch (Exception ex)
            {

            }

            return isZip;
        }
        /// <summary>
        /// 解压文件
        /// </summary>
        /// <param name="zipFilePath">压缩文件的绝对路径</param>
        public void UnZipFile(string zipFilePath)
        {
            if (!File.Exists(zipFilePath))
            {
                return;
            }
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
            {
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    string directoryName = Path.GetDirectoryName(theEntry.Name);
                    string fileName = Path.GetFileName(theEntry.Name);

                    if (!string.IsNullOrEmpty(fileName))
                    {
                        using (FileStream streamWriter = File.Create(theEntry.Name))
                        {
                            int size = 2048;
                            byte[] data = new byte[2048];

                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /// <summary>
    /// 文件排序
    /// </summary>
    public class FileComparer : IComparer<FileInfo>
    {
        /// <summary>
        /// 修改时间排序
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public int Compare(FileInfo x, FileInfo y)
        {
            return y.LastWriteTime.CompareTo(x.LastWriteTime);//递减
            //return x.LastWriteTime.CompareTo(y.LastWriteTime);//递增

            //依据名称进行排序
            //return  x.FullName.CompareTo(y.FullName);//递增
            //return y.FullName.CompareTo(x.FullName);//递减
        }
    }
}